import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.speljohan.rsbot.accessors.Player;
import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.Skills;
import com.speljohan.rsbot.script.wrappers.RSArea;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSPlayer;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class MysticSoulWars extends Script implements ServerMessageListener,
		PaintListener {

	// ***Stuff for the Blue Team***\\
	private RSTile[] BlueToBandage = { new RSTile(1807, 3232),
			new RSTile(1806, 3242), new RSTile(1808, 3254) };
	private RSArea BlueWaitRoom = new RSArea(new RSTile(1879, 3166),
			new RSTile(1870, 3158));
	private RSArea BlueGameRoom = new RSArea(new RSTile(1823, 3230),
			new RSTile(1816, 3220));
	private RSArea WestGraveYard = new RSArea(new RSTile(1843, 3219),
			new RSTile(1841, 3217));
	private RSTile blueToWestPyre[] = { new RSTile(1806, 3230),
			new RSTile(1808, 3240), new RSTile(1815, 3247),
			new RSTile(1825, 3244), new RSTile(1835, 3244),
			new RSTile(1844, 3244), new RSTile(1849, 3248) };
	private RSTile blueToObelisk[] = { new RSTile(1806, 3234),
			new RSTile(1810, 3246), new RSTile(1823, 3245),
			new RSTile(1832, 3241), new RSTile(1843, 3234),
			new RSTile(1857, 3233), new RSTile(1870, 3233),
			new RSTile(1882, 3232) };
	private RSTile blueToSouthJelly[] = { new RSTile(1808, 3229),
			new RSTile(1807, 3239), new RSTile(1813, 3248),
			new RSTile(1820, 3247), new RSTile(1826, 3242),
			new RSTile(1834, 3235), new RSTile(1843, 3231),
			new RSTile(1852, 3227), new RSTile(1857, 3219),
			new RSTile(1864, 3213), new RSTile(1872, 3210),
			new RSTile(1881, 3208) };

	// ***Stuff for the Red Team***\\
	private RSTile[] RedToBandage = { new RSTile(1967, 3237),
			new RSTile(1968, 3225), new RSTile(1969, 3216),
			new RSTile(1966, 3209) };
	private RSArea RedWaitRoom = new RSArea(new RSTile(1909, 3166), new RSTile(
			1900, 3158));
	private RSArea RedGameRoom = new RSArea(new RSTile(1951, 3234), new RSTile(
			1958, 3242));
	private RSArea EastGraveYard = new RSArea(new RSTile(1934, 3246),
			new RSTile(1932, 3244));
	private RSTile redToEastPyre[] = { new RSTile(1967, 3232),
			new RSTile(1966, 3220), new RSTile(1958, 3211),
			new RSTile(1951, 3215), new RSTile(1942, 3222),
			new RSTile(1931, 3218), new RSTile(1924, 3211) };
	private RSTile redToObelisk[] = { new RSTile(1967, 3230),
			new RSTile(1966, 3219), new RSTile(1956, 3211),
			new RSTile(1946, 3218), new RSTile(1935, 3224),
			new RSTile(1921, 3225), new RSTile(1911, 3231),
			new RSTile(1902, 3231), new RSTile(1894, 3231),
			new RSTile(1887, 3232) };
	private RSTile redToNorthJelly[] = { new RSTile(1967, 3233),
			new RSTile(1965, 3224), new RSTile(1960, 3212),
			new RSTile(1953, 3216), new RSTile(1944, 3220),
			new RSTile(1934, 3226), new RSTile(1923, 3232),
			new RSTile(1913, 3238), new RSTile(1908, 3246),
			new RSTile(1899, 3250) };

	// ***Stuff for West Graveyard***\\
	private RSTile GWestToWestPyrefiends[] = { new RSTile(1845, 3231),
			new RSTile(1849, 3242), new RSTile(1849, 3242) };
	private RSTile GWestToSouthJellys[] = { new RSTile(1855, 3218),
			new RSTile(1865, 3211), new RSTile(1875, 3207),
			new RSTile(1883, 3207) };
	private RSTile GWestToObelisk[] = { new RSTile(1853, 3226),
			new RSTile(1864, 3234), new RSTile(1875, 3233),
			new RSTile(1885, 3231) };

	// ***Stuff for East Graveyard***\\
	private RSTile GEastToEastPyrefiends[] = { new RSTile(1925, 3232),
			new RSTile(1926, 3221), new RSTile(1928, 3212) };
	private RSTile GEastToNorthJellys[] = { new RSTile(1920, 3245),
			new RSTile(1911, 3247), new RSTile(1903, 3250),
			new RSTile(1897, 3250) };
	private RSTile GEastToObelisk[] = { new RSTile(1924, 3233),
			new RSTile(1913, 3231), new RSTile(1903, 3230),
			new RSTile(1894, 3232), new RSTile(1887, 3231) };

	// ***Stuff for General Use***\\
	RSObject bandageTableBlue = findObject(42023);
	RSObject bandageTableRed = findObject(42024);
	private RSArea waitArea = new RSArea(new RSTile(1883, 3160), new RSTile(
			1895, 3164));
	private RSTile BalancePortal = new RSTile(1890, 3162);
	private RSNPC PyreFiend = getNearestNPCByID(8598);
	private RSNPC Jelly = getNearestNPCByID(8599);
	private RSNPC Barricade = getNearestNPCByID(8600, 8601);
	RSPlayer player = getRandomPlayer(10);
	String state = "";

	// ***Ints and Longs***\\
	int Dobble;
	private int bandageID = 14640;
	private int deathTime = 0;
	private int zealGained = 0;
	private int gamesCompleted = 0;
	private int soulShards = 0;
	long lvls = 0;
	long startTime = System.currentTimeMillis();
	int startLvl;
	int startExp;

	// ***Booleans***\\
	private boolean leftSpawn = false;
	private boolean randomJoin = false;
	private boolean onlyBalance = false;
	private boolean onlyRed = false;
	private boolean onlyBlue = false;
	private boolean onlyWinners = false;
	private boolean onlyLosers = false;
	private boolean KILL = false;
	private boolean AFK = false;
	private boolean FIGHT = false;
	private boolean SPECIAL = false;
	private boolean inGame = false;

	// ***Strings***\\
	private String currentTeam = null;
	private String styleOfGame = null;
	private String lastWon = null;
	private String whatJoin = null;

	// ***Areas***\\
	// RED AREA
	private int redAreaX[] = new int[] { 1900, 1901, 1908, 1909, 1909, 1908,
			1901, 1900 };
	private int redAreaY[] = new int[] { 3165, 3166, 3166, 3165, 3158, 3157,
			3157, 3158 };
	private Polygon redArea = new Polygon(redAreaX, redAreaY, 8);

	// BLUE AREA
	private int blueAreaX[] = new int[] { 1880, 1880, 1880, 1879, 1879, 1878,
			1871, 1870, 1870, 1872, 1871, 1878, 1879, 1879 };
	private int blueAreaY[] = new int[] { 3162, 3161, 3163, 3162, 3159, 3158,
			3158, 3159, 3165, 3166, 3166, 3166, 3165, 3160 };
	private Polygon blueArea = new Polygon(blueAreaX, blueAreaY, 14);

	// EAST GRAVEYARD
	private int eastGraveyardX[] = new int[] { 1939, 1927, 1929, 1938 };
	private int eastGraveyardY[] = new int[] { 3251, 3251, 3240, 3240 };
	private Polygon eastGraveyard = new Polygon(eastGraveyardX, eastGraveyardY,
			4);

	// WEST GRAVEYARD
	private int westGraveyardX[] = new int[] { 1836, 1846, 1848, 1837 };
	private int westGraveyardY[] = new int[] { 3212, 3213, 3224, 3224 };
	private Polygon westGraveyard = new Polygon(westGraveyardX, westGraveyardY,
			4);

	// BLUE HOME
	private int blueHomeX[] = new int[] { 1816, 1823, 1823, 1816 };
	private int blueHomeY[] = new int[] { 3220, 3220, 3230, 3230 };
	private Polygon blueHome = new Polygon(blueHomeX, blueHomeY, 4);

	// RED HOME
	private int redHomeX[] = new int[] { 1959, 1959, 1952, 1952 };
	private int redHomeY[] = new int[] { 3244, 3234, 3234, 3244 };
	private Polygon redHome = new Polygon(redHomeX, redHomeY, 4);

	int action = 0;
	final int JOINTEAM = 1;
	final int BANDAGEPPL = 2;
	final int TAKEBANDAGEBLUE = 3;
	final int TAKEBANDAGERED = 4;
	final int WALKTOBANDAGEBLUE = 5;
	final int WALKTOBANDAGERED = 6;
	final int LEAVEGRRED = 7;
	final int LEAVEGRBLUE = 8;
	final int LEAVEGY = 9;
	final int FIGHTPYREFIEND = 10;
	final int WALKTOPYREBLUE = 11;
	final int WALKTOPYRERED = 12;
	final int KILLPLAYERS = 13;
	final int WALKTOOBELISKBLUE = 14;
	final int WALKTOOBELISKRED = 15;

	@Override
	public String getName() {
		return "MysticSoulWars";
	}

	@Override
	public double getVersion() {
		return 1.0;
	}

	@Override
	public String getAuthor() {
		return "Mouchicc - Mystic Team";
	}

	@Override
	public String getScriptCategory() {
		return "Combat";
	}

	public String getScriptDescription() {
		String html = "<html><head>";
		html += "</head><body>";
		html += "<center><strong><h2>" + getName() + " v" + getVersion()
				+ "</h2></strong></center>";
		html += "<center>Start the script near the Blance Portal area.</center>";
		html += "<strong>What team should we join?</strong><br />";
		html += "<select name='whatJoin'>";
		html += "<option>Random Joining";
		html += "<option>Won Last";
		html += "<option>Lost Last";
		html += "<option>Balance";
		html += "<option>Join Blue";
		html += "<option>Join Red</select><br />";
		html += "<input name='optionAFK' type='checkbox' value='1'>AFK<br />";
		html += "<input name='optionKILL' type='checkbox' value='1'>Kill Players<br />";
		html += "<input name='optionFIGHT' type='checkbox' value='1'>Fight Monsters<br />";
		html += "<input name='optionSPECIAL' type='checkbox' value='1'>Special Attack<br />";
		html += "</body></html>";
		html += "";
		return html;
	}

	@Override
	public boolean onStart(Map<String, String> args) {
		AFK = args.get("optionAFK") != null ? true : false;
		KILL = args.get("optionKILL") != null ? true : false;
		FIGHT = args.get("optionFIGHT") != null ? true : false;
		SPECIAL = args.get("optionSPECIAL") != null ? true : false;

		if (AFK) {
			styleOfGame = "AFK";
		} else if (FIGHT) {
			styleOfGame = "Fight Monsters";
		} else if (KILL) {
			styleOfGame = "Kill Players";
		}

		whatJoin = args.get("whatJoin");
		if (whatJoin.equals("Random Joining")) {
			randomJoin = true;
		} else if (whatJoin.equals("Won Last")) {
			onlyWinners = true;
		} else if (whatJoin.equals("Lost Last")) {
			onlyLosers = true;
		} else if (whatJoin.equals("Balance")) {
			onlyBalance = true;
		} else if (whatJoin.equals("Join Blue")) {
			onlyBlue = true;
		} else if (whatJoin.equals("Join Red")) {
			onlyRed = true;
		} else {
			log("Team Selection Error!");
			return false;
		}
		return true;
	}

	// Easy method for eating
	private boolean check_and_heal() {
		final int MyHP = skills.getCurrentSkillLevel(STAT_HITPOINTS);
		int eatAT = random(10, 40);
		if (MyHP <= eatAT && getInventoryCount(bandageID) != 0) {
			atInventoryItem(bandageID, "Heal");
		} else {
			wait(random(20, 30));
		}
		return true;
	}

	// Types a random number
	public void enterNumber() {
		if (RSInterface.getInterface(752).getChild(4).isValid()
				&& RSInterface.getInterface(752).getChild(4).containsText(
						"How many bandages would")) {
			wait(random(400, 800));
			int rand = random(28, 999);
			Bot.getInputManager().sendKeys(Integer.toString(rand), true);
		}
	}

	private int leaveGRRed() {
		if (isRedStartingArea()) {
			inGame = true;
			currentTeam = "Red";
			RSObject redStartBarrier = getObjectAt(1959, 3239);
			RSTile redStartBar = redStartBarrier.getLocation();
			if (redStartBarrier != null) {
				if (tileOnScreen(redStartBar)) {
					if (!getMyPlayer().isMoving()) {
						setCompass('e');
						if (clickTile(redStartBarrier.getLocation(),
								"Red barrier")) {
							wait(random(500, 750));
						}
					}
				} else {
					walkTileMM(new RSTile(1959, 3239));
				}
			}
		}
		return random(50, 100);
	}

	private int leaveGRBlue() {
		if (isBlueStartingArea()) {
			inGame = true;
			currentTeam = "Blue";
			RSObject blueStartBarrier = findObject(42015);
			RSTile blueStartBar = blueStartBarrier.getLocation();
			if (blueStartBarrier != null) {
				if (tileOnScreen(blueStartBar)) {
					if (!getMyPlayer().isMoving()) {
						setCompass('w');
						if (clickTile(blueStartBarrier.getLocation(),
								"Blue barrier")) {
							wait(random(500, 750));
						}
					}
				} else {
					walkTileMM(new RSTile(1816, 3225));
				}
			}
		}
		return random(50, 100);
	}

	private int leaveGraveYard() {
		try {
			if (atArea(EastGraveYard) || playerInArea(eastGraveyard)) {
				RSObject GYDoor = findObject(42016, 42014);
				RSTile GYD = GYDoor.getLocation();
				if (GYDoor != null) {
					if (tileOnScreen(GYD)) {
						if (!getMyPlayer().isMoving()) {
							setCompass('s');
							clickTile(GYDoor.getLocation(), "Pass");
							wait(random(500, 750));
						}
					}
				}
			} else if (atArea(WestGraveYard) || playerInArea(westGraveyard)) {
				RSObject GYDoor = findObject(42016, 42014);
				RSTile GYD = GYDoor.getLocation();
				if (GYDoor != null) {
					if (tileOnScreen(GYD)) {
						if (!getMyPlayer().isMoving()) {
							setCompass('n');
							clickTile(GYDoor.getLocation(), "Pass");
							wait(random(500, 750));
						}
					}
				}
			}
		} catch (NullPointerException e) {
		}
		return random(50, 100);
	}

	public int goAction() {
		if (!inGame && isOutGame()) {
			return JOINTEAM;
		}

		if (AFK) {
			if (getInventoryCount(14640) >= 1) {
				return BANDAGEPPL;
			}

			if (currentTeam.equals("Blue")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame()) {
					return WALKTOBANDAGEBLUE;
				}

				if (bandageTableBlue != null) {
					if (tileOnScreen(bandageTableBlue.getLocation())
							&& !inventoryContains(14640)) {
						return TAKEBANDAGEBLUE;
					}
				}
			}

			if (currentTeam.equals("Red")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame() && !inventoryContains(bandageID)) {
					return WALKTOBANDAGERED;
				}

				if (bandageTableBlue != null) {
					if (tileOnScreen(bandageTableBlue.getLocation())
							&& !inventoryContains(14640)) {
						return TAKEBANDAGERED;
					}
				}
			}

		}

		if (FIGHT) {
			if (tileOnScreen(PyreFiend.getLocation())) {
				return FIGHTPYREFIEND;
			}

			if (currentTeam.equals("Blue")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame()
						&& !tileOnScreen(PyreFiend.getLocation())) {
					return WALKTOPYREBLUE;
				}
			}

			if (currentTeam.equals("Red")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame()
						&& !tileOnScreen(PyreFiend.getLocation())) {
					return WALKTOPYRERED;
				}
			}

		}

		if (KILL) {
			if (distanceTo(new RSTile(1887, 3231)) <= 5) {
				return KILLPLAYERS;
			}

			if (currentTeam.equals("Blue")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame()
						&& distanceTo(new RSTile(1887, 3231)) > 10) {
					return WALKTOOBELISKBLUE;
				}
			}

			if (currentTeam.equals("Red")) {
				if (!isBlueStartingArea() && !isRedStartingArea()
						&& !isOutGame()
						&& distanceTo(new RSTile(1887, 3231)) > 10) {
					return WALKTOOBELISKRED;
				}
			}

		}

		return 0;
	}

	// TODO
	public int loop() {
		if (getMyPlayer().isMoving()) {
			return 800;
		}

		clickContinue();

		if (isBlueStartingArea()) {
			leaveGRBlue();
		} else if (isRedStartingArea()) {
			leaveGRRed();
		}

		if (getEnergy() >= random(50, 70)) {
			setRun(true);
			wait(random(200, 500));
		}

		if (RSInterface.getChildInterface(243, 4).isValid()
				&& RSInterface.getChildInterface(243, 4).containsText(
						"You were removed from the game due")) {
			inGame = false;
		}

		if (!inGame && isOutGame()) {
			joinTheTeam();
		}

		if (atArea(EastGraveYard) || playerInArea(eastGraveyard)
				|| atArea(WestGraveYard) || playerInArea(westGraveyard)) {
			leaveGraveYard();
		}

		if (inGame) {
			if (Barricade != null && getMyPlayer().getAnimation() == -1
					&& getMyPlayer().getInteracting() == null
					&& !getMyPlayer().isMoving() && distanceTo(Barricade) <= 2) {
				clickRSNPC(Barricade, "Attack");
			}

			action = goAction();
			switch (action) {
			case JOINTEAM:
				joinTheTeam();

			case BANDAGEPPL:
				bandagePlaya(3);

			case TAKEBANDAGEBLUE:
				RSObject bandageTableBlue = findObject(42023);
				if (bandageTableBlue != null) {
					clickTile(new RSTile(1810, 3254), "Take-x");
					wait(random(1500, 3000));
					if (RSInterface.getInterface(752).getChild(4).isValid()
							&& RSInterface.getInterface(752).getChild(4)
									.containsText("How many bandages would")) {
						enterNumber();
						wait(random(600, 950));
					}
				}

			case TAKEBANDAGERED:
				RSObject bandageTableRed = findObject(42024);
				if (bandageTableRed != null) {
					clickTile(new RSTile(1963, 3208), "Take-x");
					wait(random(1500, 3000));
					if (RSInterface.getInterface(752).getChild(4).isValid()
							&& RSInterface.getInterface(752).getChild(4)
									.containsText("How many bandages would")) {
						enterNumber();
						wait(random(600, 950));
					}
				}

			case WALKTOBANDAGEBLUE:
				walkPathMM(randomizePath(BlueToBandage, 2, 2), 17);

			case WALKTOBANDAGERED:
				walkPathMM(randomizePath(RedToBandage, 2, 2), 17);

			case FIGHTPYREFIEND:
				if (!getMyPlayer().isInCombat() || !getMyPlayer().isMoving()
						|| getMyPlayer().getInteracting() == null) {
					clickRSNPC(PyreFiend, "Attack");
				}

			case WALKTOPYREBLUE:
				walkPathMM(randomizePath(blueToWestPyre, 2, 2), 17);

			case WALKTOPYRERED:
				walkPathMM(randomizePath(redToEastPyre, 2, 2), 17);

			case KILLPLAYERS:
				killPlayer(10);

			case WALKTOOBELISKBLUE:
				walkPathMM(randomizePath(blueToObelisk, 2, 2), 17);

			case WALKTOOBELISKRED:
				walkPathMM(randomizePath(redToObelisk, 2, 2), 17);
			}
		}

		return (random(50, 100));
	}

	// Joins the Red Team
	public int joinRedTeam() {
		try {
			RSObject redBarrier = findObject(42216);
			RSTile redBar = redBarrier.getLocation();
			if (playerInArea(1909, 3157, 1900, 3166) || atArea(RedWaitRoom)) {
				currentTeam = "Red";
				wait(random(1000, 2000));
			} else if (tileOnScreen(redBar)) {
				clickTile(redBarrier.getLocation(), "pass");
				wait(random(800, 1000));
			} else {
				walkTileMM(redBar);
				wait(random(1000, 2500));
				clickTile(redBarrier.getLocation(), "pass");
				return random(150, 300);
			}

			if (leftEarly()) {
				int waitTime = howLong();
				int randTime = howLong() + random(1000, 5000);
				log("We must wait " + waitTime + " more minutes!");
				wait(random(waitTime, randTime));
				return random(50, 150);
			}

			while (atInterface(RSInterface.getInterface(211).getChild(3))
					|| atInterface(RSInterface.getInterface(228).getChild(2))) {
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(211).getChild(3))) {
					clickMouse(190 + random(0, 140), 445 + random(0, 15), true);
				}
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(228).getChild(2))) {
					clickMouse(220 + random(0, 80), 395 + random(0, 15), true);
				}
				wait(random(800, 1000));
				wait(random(1000, 2000));
			}

			if (atArea(RedWaitRoom)
					|| getMyPlayer().getLocation().getX() == 1900
					&& getMyPlayer().getLocation().getX() == 3162) {
				currentTeam = "Red";
				wait(random(1000, 2000));
			}
		} catch (NullPointerException e) {
		}
		return random(50, 150);
	}

	// Join the Blue Team
	private int joinBlueTeam() {
		try {
			RSObject blueBarrier = findObject(42029);
			RSTile blueBar = blueBarrier.getLocation();
			if (playerInArea(1909, 3157, 1900, 3166) || atArea(RedWaitRoom)) {
				currentTeam = "Red";
				wait(random(1000, 2000));
			} else if (tileOnScreen(blueBar)) {
				clickTile(blueBarrier.getLocation(), "pass");
				wait(random(800, 1000));
			} else {
				walkTileMM(blueBar);
				wait(random(1000, 2500));
				clickTile(blueBarrier.getLocation(), "pass");
				return random(150, 300);
			}

			if (leftEarly()) {
				int waitTime = howLong();
				int randTime = howLong() + random(1000, 5000);
				log("We must wait " + waitTime + " more minutes!");
				wait(random(waitTime, randTime));
				return random(50, 150);
			}

			while (atInterface(RSInterface.getInterface(211).getChild(3))
					|| atInterface(RSInterface.getInterface(228).getChild(2))) {
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(211).getChild(3))) {
					clickMouse(190 + random(0, 140), 445 + random(0, 15), true);
				}
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(228).getChild(2))) {
					clickMouse(220 + random(0, 80), 395 + random(0, 15), true);
				}
				wait(random(800, 1000));
				wait(random(1000, 2000));
			}

			if (atArea(RedWaitRoom)
					|| getMyPlayer().getLocation().getX() == 1900
					&& getMyPlayer().getLocation().getX() == 3162) {
				currentTeam = "Red";
				wait(random(1000, 2000));
			}
		} catch (NullPointerException e) {
		}
		return random(50, 150);
	}

	// Join at the Balance Portal
	public int joinBalance() {
		try {
			if (playerInArea(1879, 3157, 1870, 3166) || atArea(BlueWaitRoom)) {
				currentTeam = "Blue";
				wait(random(1000, 2000));
			} else if (playerInArea(1909, 3157, 1900, 3166)
					|| atArea(RedWaitRoom)) {
				currentTeam = "Red";
				wait(random(1000, 2000));
			} else if (distanceTo(BalancePortal) <= 5 || atArea(waitArea)) {
				clickTile(BalancePortal, "Join-team");
				wait(random(800, 1000));
			} else {
				walkTileMM(BalancePortal);
				wait(random(1000, 2500));
				clickTile(BalancePortal, "Join-team");
			}

			if (leftEarly()) {
				int waitTime = howLong();
				int randTime = howLong() + random(1000, 5000);
				log("We must wait " + waitTime + " more minutes!");
				wait(random(waitTime, randTime));
				return random(50, 150);
			}

			while (atInterface(RSInterface.getInterface(211).getChild(3))
					|| atInterface(RSInterface.getInterface(228).getChild(2))) {
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(211).getChild(3))) {
					clickMouse(190 + random(0, 140), 445 + random(0, 15), true);
				}
				wait(random(800, 1000));
				if (atInterface(RSInterface.getInterface(228).getChild(2))) {
					clickMouse(220 + random(0, 80), 395 + random(0, 15), true);
				}
				wait(random(800, 1000));
				wait(random(1000, 2000));
			}

		} catch (NullPointerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return random(50, 150);
	}

	// Joins the team you select
	private void joinTheTeam() {
		if (randomJoin) {
			int GambleInt = random(1, 3);
			if (GambleInt == 1) {
				joinRedTeam();
			} else if (GambleInt == 2) {
				joinBlueTeam();
			} else if (GambleInt == 3) {
				joinBalance();
			}
		}

		if (onlyRed) {
			joinRedTeam();
			return;
		}

		if (onlyBlue) {
			joinBlueTeam();
			return;
		}

		if (onlyBalance) {
			joinBalance();
			return;
		}

		if (onlyWinners) {
			if (lastWon == null) {
				joinBalance();
			}
			if (lastWon == "Red") {
				joinRedTeam();
			}
			if (lastWon == "Blue") {
				joinBlueTeam();
			}
			return;
		}

		if (onlyLosers) {
			if (lastWon == null) {
				joinBalance();
			}
			if (lastWon == "Red") {
				joinBlueTeam();
			}
			if (lastWon == "Blue") {
				joinRedTeam();
			}
			return;
		}
	}

	// Gets Special
	public int getSpec() {
		return getSetting(300);
	}

	// Gets if Special is Enabled
	public boolean specEnabled() {
		return (getSetting(301)) == 1;
	}

	// Does Special!
	public void doSpec() {
		if (getSpec() >= 1000 && !specEnabled() && SPECIAL == true) {
			openTab(Constants.TAB_ATTACK);
			clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
			wait(350);
		}
		return;
	}

	String lastmessage = null;
	String checkMessage = null;

	// ServerMessage thingys
	public void serverMessageRecieved(ServerMessageEvent e) {
		String messageEvent = e.getMessage();

		if (messageEvent == lastmessage
				&& (!messageEvent.contains("you are dead") || !messageEvent
						.contains("gave you some soul fragments"))) {
			return;
		}

		lastmessage = e.getMessage();
		checkMessage = e.getMessage();

		if (messageEvent.contains("you are dead")) {
			log("You have died. All soul fragments were lost.");
			soulShards = 0;
			deathTime++;
		}
		if (messageEvent.contains("gave you some soul fragments")) {
			log("You have gained some soul fragments.");
			soulShards++;
		}
		if (messageEvent.contains("participation")) {
			gamesCompleted++;
			if (messageEvent.contains("3 Zeal")) {
				zealGained += 3;
				log("We have gained 3 Zeal.");
			} else if (messageEvent.contains("2 Zeal")) {
				zealGained += 2;
				log("We have gained 2 Zeal.");
			} else if (messageEvent.contains("1 Zeal")) {
				zealGained += 1;
				log("We have gained 1 Zeal.");
			}
			if (messageEvent.contains("was drawn")) {
				lastWon = null;
				log("It was a draw!");
				reset();
			} else if (messageEvent.contains("blue")) {
				lastWon = "Blue";
				log("Blue team won!");
				reset();
			} else if (messageEvent.contains("red")) {
				lastWon = "Red";
				log("Red team won!");
				reset();
			}
		}
	}

	int xpgained = 0;
	int skillATT = 0;
	int skillSTR = 0;
	int skillDEF = 0;
	int skillRNG = 0;
	int skillMAG = 0;
	int skillHIT = 0;
	int skillSLY = 0;
	int skillPRY = 0;
	int[] skillArray;
	String[] nameArray;

	private boolean setupSkills() {
		skillATT = skills.getCurrentSkillExp(Skills.getStatIndex("attack"));
		skillSTR = skills.getCurrentSkillExp(Skills.getStatIndex("strength"));
		skillDEF = skills.getCurrentSkillExp(Skills.getStatIndex("defence"));
		skillRNG = skills.getCurrentSkillExp(Skills.getStatIndex("range"));
		skillMAG = skills.getCurrentSkillExp(Skills.getStatIndex("magic"));
		skillHIT = skills.getCurrentSkillExp(Skills.getStatIndex("hitpoints"));
		skillSLY = skills.getCurrentSkillExp(Skills.getStatIndex("slayer"));
		skillPRY = skills.getCurrentSkillExp(Skills.getStatIndex("prayer"));
		skillArray = new int[] { skillATT, skillSTR, skillDEF, skillHIT,
				skillRNG, skillMAG, skillPRY, skillSLY };
		nameArray = new String[] { "Attack", "Strength", "Defense",
				"Hitpoints", "Range", "Magic", "Prayer", "Slayer" };

		return false;
	}

	boolean setupSkills = false;

	public void onRepaint(Graphics g) {
		long runTime = 0;
		long seconds = 0;
		long minutes = 0;
		long hours = 0;

		runTime = System.currentTimeMillis() - startTime;
		seconds = runTime / 1000;
		if (seconds >= 60) {
			minutes = seconds / 60;
			seconds -= (minutes * 60);
		}
		if (minutes >= 60) {
			hours = minutes / 60;
			minutes -= (hours * 60);
		}

		if (!setupSkills) {
			setupSkills();
			setupSkills = true;
		}

		int coordCount = 0;

		if (getCurrentTab() == TAB_INVENTORY) {
			g.setColor(new Color(0, 0, 0, 100));
			g.fillRoundRect(555, 210, 175, 250, 10, 10);
			g.setColor(Color.WHITE);

			int[] coords = new int[] { 225, 240, 255, 270, 285, 300, 315, 330,
					345, 360, 375, 390, 405, 420, 435, 450 };

			g.drawString("Run Time: " + hours + ":" + minutes + ":" + seconds,
					561, coords[1]);
			g.setColor(Color.WHITE);
			g.drawString("Games Completed: " + gamesCompleted, 561, coords[2]);
			g.setColor(Color.WHITE);
			g.drawString("Zeal Gained: " + zealGained, 561, coords[3]);

			skillATT = skills.getCurrentSkillExp(Skills.getStatIndex("attack"));
			skillSTR = skills.getCurrentSkillExp(Skills
					.getStatIndex("strength"));
			skillDEF = skills
					.getCurrentSkillExp(Skills.getStatIndex("defence"));
			skillRNG = skills.getCurrentSkillExp(Skills.getStatIndex("range"));
			skillMAG = skills.getCurrentSkillExp(Skills.getStatIndex("magic"));
			skillHIT = skills.getCurrentSkillExp(Skills
					.getStatIndex("hitpoints"));
			skillSLY = skills.getCurrentSkillExp(Skills.getStatIndex("slayer"));
			skillPRY = skills.getCurrentSkillExp(Skills.getStatIndex("prayer"));
			int[] newSkillArray = new int[] { skillATT, skillSTR, skillDEF,
					skillHIT, skillRNG, skillMAG, skillPRY, skillSLY };

			for (int i = 0; i < 8; i++) {
				xpgained = newSkillArray[i] - skillArray[i];
				if (xpgained == 0)
					continue;
				g.drawString(nameArray[i] + " XP: " + xpgained, 561,
						coords[(5 + coordCount)]);
				coordCount++;
			}

			g.drawString("Team Method: " + whatJoin, 561, coords[14]);
			g.drawString("In-Game Action: " + styleOfGame, 561, coords[15]);
		}

	}

	// Checks if we are in an area
	public boolean atArea(RSArea area) {
		if (area.contains(getMyPlayer().getLocation())) {
			return true;
		}
		return false;
	}

	// Gets a randomPlayer at a maxDistance
	public RSPlayer getRandomPlayer(final int maxDistance) {
		ArrayList<RSPlayer> playersList = new ArrayList<RSPlayer>();
		final int[] validPlayers = Bot.getClient().getPlayerIndexArray();
		final Player[] players = Bot.getClient().getPlayerArray();

		for (final int element : validPlayers) {
			if (element >= players.length)
				continue;
			if (players[element] == null) {
				continue;
			}
			final RSPlayer player = new RSPlayer(players[element]);
			try {
				if (distanceTo(player) < maxDistance) {
					playersList.add(player);
				}
			} catch (final Exception e) {
				// e.printStackTrace(); TODO: Why?
			}
		}
		return playersList.get(random(0, playersList.size()));
	}

	// Clicks a NPC by Ruski
	public boolean clickNPC(RSNPC npc, String action) {
		if (npc == null) {
			return false;
		}
		RSTile tile = npc.getLocation();
		if (!tile.isValid()) {
			return false;
		}

		try {
			Point screenLoc = npc.getScreenLocation();
			if (distanceTo(tile) > 6 || !pointOnScreen(screenLoc)) {
				turnToTile(tile);
			}
			if (distanceTo(tile) > 20) {
				walkTileMM(tile);
				return false;
			}
			for (int i = 0; i < 12; i++) {
				screenLoc = npc.getScreenLocation();
				if (!npc.isValid() || !pointOnScreen(screenLoc)) {
					return false;
				}
				moveMouse(screenLoc, 5, 5);
				if (getMenuItems().get(0).toLowerCase().contains(
						npc.getName().toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
			}
			List<String> menuItems = getMenuItems();
			if (menuItems.isEmpty()) {
				return false;
			}
			for (int a = 0; a < menuItems.size(); a++) {
				if (menuItems.get(a).toLowerCase().contains(
						npc.getName().toLowerCase())) {
					if (menuItems.get(0).toLowerCase().contains(
							action.toLowerCase())) {
						clickMouse(true);
						return true;
					} else {
						clickMouse(false);
						return atMenu(action);
					}
				}
			}
		} catch (Exception e) {
			System.out.print("clickNPC(RSNPC, String) error: " + e);
			return false;
		}
		return false;
	}

	// Resets the values after each game
	public void reset() {
		deathTime = 0;
		currentTeam = null;
	}

	// Gets if the player is in an Area
	public boolean playerInArea(int maxX, int minY, int minX, int maxY) {
		int x = getMyPlayer().getLocation().getX();
		int y = getMyPlayer().getLocation().getY();
		if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
			return true;
		}
		return false;
	}

	// Gets if the playa is in a Polygon Area
	public boolean playerInArea(Polygon area) {
		return area.contains(new Point(getMyPlayer().getLocation().getX(),
				getMyPlayer().getLocation().getY()));
	}

	// clickTile method by DDM
	public boolean clickTile(RSTile tile, String option) {
		Point p = Calculations.tileToScreen(tile);
		p.x += random(-5, 6);
		p.y += random(-5, 6);
		if (p.x < 0 || p.y < 0) {
			return false;
		}
		moveMouse(p);
		// wait(random(100,150));
		getMenuItems();
		List<String> itemsList = getMenuItems();

		long waitTime = System.currentTimeMillis() + random(50, 250);
		boolean foundOption = false;
		while (System.currentTimeMillis() < waitTime && !foundOption) {
			wait(15);
			foundOption = (itemsList = getMenuItems()).get(0).toLowerCase()
					.contains(option.toLowerCase());
		}
		if (foundOption) {
			clickMouse(true);
			wait(random(150, 300));
			return true;
		}
		clickMouse(false);
		wait(random(150, 300));
		return atMenu(option);
	}

	// Method for clicking an inventoryItem
	public boolean clickInventoryItem(int itemID, String option) {
		if (getCurrentTab() != TAB_INVENTORY) {
			openTab(TAB_INVENTORY);
		}
		int[] items = getInventoryArray();
		java.util.List<Integer> possible = new ArrayList<Integer>();
		for (int i = 0; i < items.length; i++) {
			if (items[i] == itemID) {
				possible.add(i);
			}
		}
		if (possible.size() == 0) {
			return false;
		}
		int idx = possible.get(random(0, possible.size()));
		Point t = getInventoryItemPoint(idx);
		moveMouse(t, 5, 5);
		long waitTime = System.currentTimeMillis() + random(50, 250);
		boolean found = false;
		while (!found && System.currentTimeMillis() < waitTime) {
			wait(15);
			if ((getMenuItems()).get(0).toLowerCase().contains(
					option.toLowerCase())) {
				found = true;
			}
		}
		if (found) {
			clickMouse(true);
			wait(random(150, 250));
			return true;
		}
		clickMouse(false);
		wait(random(150, 250));
		return atMenu(option);
	}

	public void setRetaliateOff() {
		if (isRetaliateEnabled()) {
			if (getCurrentTab() != TAB_ATTACK) {
				openTab(TAB_ATTACK);
			}
			wait(random(1000, 2000));
			try {
				moveMouse(random(590, 690), random(370, 390));
				wait(random(500, 1000));
				clickMouse(true);
				log("Set auto-retaliate OFF");
			} catch (Exception e) {

			}
		}
		return;
	}

	// Checks if players left early
	private boolean leftEarly() {
		if (RSInterface.getChildInterface(211, 1).isValid()
				&& RSInterface.getChildInterface(211, 1).getText().contains(
						"left a game")) {
			return true;
		} else
			return false;
	}

	// How long till the next game (by Garrett)
	private int howLong() {
		String getLine = RSInterface.getChildInterface(211, 1).getText();
		String subLine = getLine.substring(getLine.indexOf("wait ") + 5,
				getLine.indexOf(" minutes"));
		return Integer.parseInt(subLine);
	}

	// Kills players at between a maxDistance
	public RSPlayer killPlayer(final int maxDistance) {
		RSPlayer playa = null;
		ArrayList<RSPlayer> playersList = new ArrayList<RSPlayer>();
		int[] validPlayers = Bot.getClient().getPlayerIndexArray();
		final Player[] players = Bot.getClient().getPlayerArray();

		for (final int element : validPlayers) {
			if (element >= players.length)
				continue;
			if (players[element] == null) {
				continue;
			}
			playa = new RSPlayer(players[element]);
			try {
				RSTile targetLoc = playa.getLocation();
				Point checkPlayer = Calculations.tileToScreen(targetLoc);
				if (distanceTo(playa) < maxDistance) {
					playersList.add(playa);
				}
				if (!pointOnScreen(checkPlayer)) {
					continue;
				}
				if (getMyPlayer().getTeam() != playa.getTeam()
						&& !getMyPlayer().isInCombat()
						&& getMyPlayer().getInteracting() == null) {
					atPlayer(playa, "Attack");
				}
			} catch (final Exception e) {
				// e.printStackTrace(); TODO: Why?
			}
		}
		return playersList.get(random(0, playersList.size()));
	}

	public boolean isBlueStartingArea() {
		int x = getMyPlayer().getLocation().getX();
		int y = getMyPlayer().getLocation().getY();
		return x >= 1816 && x <= 1823 && y >= 3220 && y <= 3230;
	}

	public boolean isRedStartingArea() {
		int x = getMyPlayer().getLocation().getX();
		int y = getMyPlayer().getLocation().getY();
		return x >= 1952 && x <= 1958 && y >= 3234 && y <= 3243;
	}

	public boolean isOutGame() {
		int x = getMyPlayer().getLocation().getX();
		int y = getMyPlayer().getLocation().getY();
		return x >= 1872 && x <= 1899 && y >= 3153 && y <= 3182;
	}

	// Bandages players
	public RSPlayer bandagePlaya(final int maxDistance) {
		RSPlayer player = null;
		ArrayList<RSPlayer> playersList = new ArrayList<RSPlayer>();
		int[] validPlayers = Bot.getClient().getPlayerIndexArray();
		final Player[] players = Bot.getClient().getPlayerArray();

		for (final int element : validPlayers) {
			if (players[element] == null) {
				continue;
			}
			player = new RSPlayer(players[element]);
			try {
				Point checkPlayer = Calculations.tileToScreen(player
						.getLocation());
				if (distanceTo(player) > 10) {
					continue;
				}
				if (distanceTo(player) < maxDistance) {
					playersList.add(player);
				}
				if (!pointOnScreen(checkPlayer)) {
					continue;
				}
				if (isOutGame() || !inGame) {
					clickMouse(true);
					inGame = false;
					break;
				}
				if (!inventoryContains(14640) || isBlueStartingArea()
						|| isRedStartingArea()) {
					break;
				}
				if (currentTeam.equals("Blue")) {
					RSObject bandageTableBlue = findObject(42023);
					if (bandageTableBlue != null) {
						if (distanceTo(bandageTableBlue.getLocation()) > 10) {
							walkTileMM(bandageTableBlue.getLocation());
						}
					}
				} else {
					RSObject bandageTableRed = findObject(42024);
					if (bandageTableRed != null) {
						if (distanceTo(bandageTableRed.getLocation()) > 10) {
							walkTileMM(bandageTableRed.getLocation());
						}
					}
				}
				if (inventoryContains(14640)) {
					clickInventoryItem(14640, "use");
					wait(random(700, 900));
					String name = player.getName();
					moveMouse(checkPlayer, 2, 2);
					wait(random(500, 750));
					validPlayers = Bot.getClient().getPlayerIndexArray();
					clickCharacter(player, "use bandages -> " + name);
				}
				return player;
			} catch (final Exception e) {
				// e.printStackTrace(); TODO: Why?
			}
		}
		return playersList.get(random(0, playersList.size()));
	}

	public boolean useBandagesOnOtherPlayer() {
		RSPlayer player = null;
		int[] validPlayers = Bot.getClient().getPlayerIndexArray();
		Player[] players = Bot.getClient().getPlayerArray();

		for (int element : validPlayers) {
			wait(random(5000, 15000));
			if (players[element] == null) {
				continue;
			}
			player = new RSPlayer(players[element]);
			try {
				RSTile targetLoc = player.getLocation();
				Point checkPlayer = Calculations.tileToScreen(targetLoc);
				if (distanceTo(targetLoc) > 10) {
					continue;
				}
				if (!pointOnScreen(checkPlayer)) {
					continue;
				}
				if (isOutGame() || !inGame) {
					clickMouse(true);
					inGame = false;
					break;
				}
				if (!inventoryContains(14640) || isBlueStartingArea()
						|| isRedStartingArea()) {
					break;
				}
				if (currentTeam.equals("Blue")) {
					RSObject bandageTableBlue = findObject(42023);
					if (bandageTableBlue != null) {
						if (distanceTo(bandageTableBlue.getLocation()) > 10) {
							walkTileMM(bandageTableBlue.getLocation());
						}
					}
				} else {
					RSObject bandageTableRed = findObject(42024);
					if (bandageTableRed != null) {
						if (distanceTo(bandageTableRed.getLocation()) > 10) {
							walkTileMM(bandageTableRed.getLocation());
						}
					}
				}
				if (inventoryContains(14640)) {
					clickInventoryItem(14640, "use");
					wait(random(700, 900));
					String name = player.getName();
					moveMouse(checkPlayer, 2, 2);
					wait(random(500, 750));
					clickMouse(false);
					validPlayers = Bot.getClient().getPlayerIndexArray();
					atMenu("use bandages -> " + name);
				}
				return true;
			} catch (Exception e) {
			}
		}
		return player != null;
	}

}